#include "ioctls.h"
#include "net.h"
#include "shm.h"
#include "utils.h"

static int socket_fd_test(int fd, const struct stat *st __attribute__((unused)))
{
	struct list_head *globallist, *node;

	globallist = shm->global_objects[OBJ_FD_SOCKET].list;

	list_for_each(node, globallist) {
		struct object *obj;
		struct socketinfo *si;

		obj = (struct object *) node;
		si = &obj->sockinfo;

		if (si->fd == fd)
			return 0;
	}

	return -1;
}

static const struct ioctl socket_ioctls[] = {
	{ .name = "FIOSETOWN", .request = 0x8901, },
	{ .name = "SIOCSPGRP", .request = 0x8902, },
	{ .name = "FIOGETOWN", .request = 0x8903, },
	{ .name = "SIOCGPGRP", .request = 0x8904, },
	{ .name = "SIOCATMARK", .request = 0x8905, },
	{ .name = "SIOCGSTAMP", .request = 0x8906, },
	{ .name = "SIOCGSTAMPNS", .request = 0x8907, },

	{ .name = "SIOCADDRT", .request = 0x890B, },
	{ .name = "SIOCDELRT", .request = 0x890C, },
	{ .name = "SIOCRTMSG", .request = 0x890D, },
	{ .name = "SIOCGIFNAME", .request = 0x8910, },
	{ .name = "SIOCSIFLINK", .request = 0x8911, },
	{ .name = "SIOCGIFCONF", .request = 0x8912, },
	{ .name = "SIOCGIFFLAGS", .request = 0x8913, },
	{ .name = "SIOCSIFFLAGS", .request = 0x8914, },
	{ .name = "SIOCGIFADDR", .request = 0x8915, },
	{ .name = "SIOCSIFADDR", .request = 0x8916, },
	{ .name = "SIOCGIFDSTADDR", .request = 0x8917, },
	{ .name = "SIOCSIFDSTADDR", .request = 0x8918, },
	{ .name = "SIOCGIFBRDADDR", .request = 0x8919, },
	{ .name = "SIOCSIFBRDADDR", .request = 0x891a, },
	{ .name = "SIOCGIFNETMASK", .request = 0x891b, },
	{ .name = "SIOCSIFNETMASK", .request = 0x891c, },
	{ .name = "SIOCGIFMETRIC", .request = 0x891d, },
	{ .name = "SIOCSIFMETRIC", .request = 0x891e, },
	{ .name = "SIOCGIFMEM", .request = 0x891f, },
	{ .name = "SIOCSIFMEM", .request = 0x8920, },
	{ .name = "SIOCGIFMTU", .request = 0x8921, },
	{ .name = "SIOCSIFMTU", .request = 0x8922, },
	{ .name = "SIOCSIFNAME", .request = 0x8923, },
	{ .name = "SIOCSIFHWADDR", .request = 0x8924, },
	{ .name = "SIOCGIFENCAP", .request = 0x8925, },
	{ .name = "SIOCSIFENCAP", .request = 0x8926, },
	{ .name = "SIOCGIFHWADDR", .request = 0x8927, },
	{ .name = "SIOCGIFSLAVE", .request = 0x8929, },
	{ .name = "SIOCSIFSLAVE", .request = 0x8930, },
	{ .name = "SIOCADDMULTI", .request = 0x8931, },
	{ .name = "SIOCDELMULTI", .request = 0x8932, },
	{ .name = "SIOCGIFINDEX", .request = 0x8933, },
	{ .name = "SIOCSIFPFLAGS", .request = 0x8934, },
	{ .name = "SIOCGIFPFLAGS", .request = 0x8935, },
	{ .name = "SIOCDIFADDR", .request = 0x8936, },
	{ .name = "SIOCSIFHWBROADCAST", .request = 0x8937, },
	{ .name = "SIOCGIFCOUNT", .request = 0x8938, },
	{ .name = "SIOCGIFBR", .request = 0x8940, },
	{ .name = "SIOCSIFBR", .request = 0x8941, },
	{ .name = "SIOCGIFTXQLEN", .request = 0x8942, },
	{ .name = "SIOCSIFTXQLEN", .request = 0x8943, },
	{ .name = "SIOCETHTOOL", .request = 0x8946, },
	{ .name = "SIOCGMIIPHY", .request = 0x8947, },
	{ .name = "SIOCGMIIREG", .request = 0x8948, },
	{ .name = "SIOCSMIIREG", .request = 0x8949, },
	{ .name = "SIOCWANDEV", .request = 0x894A, },
	{ .name = "SIOCDARP", .request = 0x8953, },
	{ .name = "SIOCGARP", .request = 0x8954, },
	{ .name = "SIOCSARP", .request = 0x8955, },
	{ .name = "SIOCDRARP", .request = 0x8960, },
	{ .name = "SIOCGRARP", .request = 0x8961, },
	{ .name = "SIOCSRARP", .request = 0x8962, },
	{ .name = "SIOCGIFMAP", .request = 0x8970, },
	{ .name = "SIOCSIFMAP", .request = 0x8971, },
	{ .name = "SIOCADDDLCI", .request = 0x8980, },
	{ .name = "SIOCDELDLCI", .request = 0x8981, },
	{ .name = "SIOCGIFVLAN", .request = 0x8982, },
	{ .name = "SIOCSIFVLAN", .request = 0x8983, },
	{ .name = "SIOCBONDENSLAVE", .request = 0x8990, },
	{ .name = "SIOCBONDRELEASE", .request = 0x8991, },
	{ .name = "SIOCBONDSETHWADDR", .request = 0x8992, },
	{ .name = "SIOCBONDSLAVEINFOQUERY", .request = 0x8993, },
	{ .name = "SIOCBONDINFOQUERY", .request = 0x8994, },
	{ .name = "SIOCBONDCHANGEACTIVE", .request = 0x8995, },
	{ .name = "SIOCBRADDBR", .request = 0x89a0, },
	{ .name = "SIOCBRDELBR", .request = 0x89a1, },
	{ .name = "SIOCBRADDIF", .request = 0x89a2, },
	{ .name = "SIOCBRDELIF", .request = 0x89a3, },
	{ .name = "SIOCSHWTSTAMP", .request = 0x89b0, },
	{ .name = "SIOCGHWTSTAMP", .request = 0x89b1, },

	{ .name = "SIOCPROTOPRIVATE1", .request = 0x89e0, },
	{ .name = "SIOCPROTOPRIVATE2", .request = 0x89e1, },
	{ .name = "SIOCPROTOPRIVATE3", .request = 0x89e2, },
	{ .name = "SIOCPROTOPRIVATE4", .request = 0x89e3, },
	{ .name = "SIOCPROTOPRIVATE5", .request = 0x89e4, },
	{ .name = "SIOCPROTOPRIVATE6", .request = 0x89e5, },
	{ .name = "SIOCPROTOPRIVATE7", .request = 0x89e6, },
	{ .name = "SIOCPROTOPRIVATE8", .request = 0x89e7, },
	{ .name = "SIOCPROTOPRIVATE9", .request = 0x89e8, },
	{ .name = "SIOCPROTOPRIVATE10", .request = 0x89e9, },
	{ .name = "SIOCPROTOPRIVATE11", .request = 0x89ea, },
	{ .name = "SIOCPROTOPRIVATE12", .request = 0x89eb, },
	{ .name = "SIOCPROTOPRIVATE13", .request = 0x89ec, },
	{ .name = "SIOCPROTOPRIVATE14", .request = 0x89ed, },
	{ .name = "SIOCPROTOPRIVATE15", .request = 0x89ee, },
	{ .name = "SIOCPROTOPRIVATE16", .request = 0x89ef, },
	{ .name = "SIOCDEVPRIVATE1", .request = 0x89f0, },
	{ .name = "SIOCDEVPRIVATE2", .request = 0x89f1, },
	{ .name = "SIOCDEVPRIVATE3", .request = 0x89f2, },
	{ .name = "SIOCDEVPRIVATE4", .request = 0x89f3, },
	{ .name = "SIOCDEVPRIVATE5", .request = 0x89f4, },
	{ .name = "SIOCDEVPRIVATE6", .request = 0x89f5, },
	{ .name = "SIOCDEVPRIVATE7", .request = 0x89f6, },
	{ .name = "SIOCDEVPRIVATE8", .request = 0x89f7, },
	{ .name = "SIOCDEVPRIVATE9", .request = 0x89f8, },
	{ .name = "SIOCDEVPRIVATE10", .request = 0x89f9, },
	{ .name = "SIOCDEVPRIVATE11", .request = 0x89fa, },
	{ .name = "SIOCDEVPRIVATE12", .request = 0x89fb, },
	{ .name = "SIOCDEVPRIVATE13", .request = 0x89fc, },
	{ .name = "SIOCDEVPRIVATE14", .request = 0x89fd, },
	{ .name = "SIOCDEVPRIVATE15", .request = 0x89fe, },
	{ .name = "SIOCDEVPRIVATE16", .request = 0x89ff, },

	{ .name = "SIOCSIWCOMMIT", .request = 0x8B00, },
	{ .name = "SIOCGIWNAME", .request = 0x8B01, },
	{ .name = "SIOCSIWNWID", .request = 0x8B02, },
	{ .name = "SIOCGIWNWID", .request = 0x8B03, },
	{ .name = "SIOCSIWFREQ", .request = 0x8B04, },
	{ .name = "SIOCGIWFREQ", .request = 0x8B05, },
	{ .name = "SIOCSIWMODE", .request = 0x8B06, },
	{ .name = "SIOCGIWMODE", .request = 0x8B07, },
	{ .name = "SIOCSIWSENS", .request = 0x8B08, },
	{ .name = "SIOCGIWSENS", .request = 0x8B09, },
	{ .name = "SIOCSIWRANGE", .request = 0x8B0A, },
	{ .name = "SIOCGIWRANGE", .request = 0x8B0B, },
	{ .name = "SIOCSIWPRIV", .request = 0x8B0C, },
	{ .name = "SIOCGIWPRIV", .request = 0x8B0D, },
	{ .name = "SIOCSIWSTATS", .request = 0x8B0E, },
	{ .name = "SIOCGIWSTATS", .request = 0x8B0F, },
	{ .name = "SIOCSIWSPY", .request = 0x8B10, },
	{ .name = "SIOCGIWSPY", .request = 0x8B11, },
	{ .name = "SIOCSIWTHRSPY", .request = 0x8B12, },
	{ .name = "SIOCGIWTHRSPY", .request = 0x8B13, },
	{ .name = "SIOCSIWAP", .request = 0x8B14, },
	{ .name = "SIOCGIWAP", .request = 0x8B15, },
	{ .name = "SIOCGIWAPLIST", .request = 0x8B17, },
	{ .name = "SIOCSIWSCAN", .request = 0x8B18, },
	{ .name = "SIOCGIWSCAN", .request = 0x8B19, },
	{ .name = "SIOCSIWESSID", .request = 0x8B1A, },
	{ .name = "SIOCGIWESSID", .request = 0x8B1B, },
	{ .name = "SIOCSIWNICKN", .request = 0x8B1C, },
	{ .name = "SIOCGIWNICKN", .request = 0x8B1D, },
	{ .name = "SIOCSIWRATE", .request = 0x8B20, },
	{ .name = "SIOCGIWRATE", .request = 0x8B21, },
	{ .name = "SIOCSIWRTS", .request = 0x8B22, },
	{ .name = "SIOCGIWRTS", .request = 0x8B23, },
	{ .name = "SIOCSIWFRAG", .request = 0x8B24, },
	{ .name = "SIOCGIWFRAG", .request = 0x8B25, },
	{ .name = "SIOCSIWTXPOW", .request = 0x8B26, },
	{ .name = "SIOCGIWTXPOW", .request = 0x8B27, },
	{ .name = "SIOCSIWRETRY", .request = 0x8B28, },
	{ .name = "SIOCGIWRETRY", .request = 0x8B29, },
	{ .name = "SIOCSIWENCODE", .request = 0x8B2A, },
	{ .name = "SIOCGIWENCODE", .request = 0x8B2B, },
	{ .name = "SIOCSIWPOWER", .request = 0x8B2C, },
	{ .name = "SIOCGIWPOWER", .request = 0x8B2D, },
	{ .name = "SIOCSIWGENIE", .request = 0x8B30, },
	{ .name = "SIOCGIWGENIE", .request = 0x8B31, },
	{ .name = "SIOCSIWMLME", .request = 0x8B16, },
	{ .name = "SIOCSIWAUTH", .request = 0x8B32, },
	{ .name = "SIOCGIWAUTH", .request = 0x8B33, },
	{ .name = "SIOCSIWENCODEEXT", .request = 0x8B34, },
	{ .name = "SIOCGIWENCODEEXT", .request = 0x8B35, },
	{ .name = "SIOCSIWPMKSA", .request = 0x8B36, },
	{ .name = "SIOCIWFIRSTPRIV", .request = 0x8BE0, },
	{ .name = "SIOCIWPRIV2", .request = 0x8BE1, },
	{ .name = "SIOCIWPRIV3", .request = 0x8BE2, },
	{ .name = "SIOCIWPRIV4", .request = 0x8BE3, },
	{ .name = "SIOCIWPRIV5", .request = 0x8BE4, },
	{ .name = "SIOCIWPRIV6", .request = 0x8BE5, },
	{ .name = "SIOCIWPRIV7", .request = 0x8BE6, },
	{ .name = "SIOCIWPRIV8", .request = 0x8BE7, },
	{ .name = "SIOCIWPRIV9", .request = 0x8BE8, },
	{ .name = "SIOCIWPRIV10", .request = 0x8BE9, },
	{ .name = "SIOCIWPRIV11", .request = 0x8BEA, },
	{ .name = "SIOCIWPRIV12", .request = 0x8BEB, },
	{ .name = "SIOCIWPRIV13", .request = 0x8BEC, },
	{ .name = "SIOCIWPRIV14", .request = 0x8BED, },
	{ .name = "SIOCIWPRIV15", .request = 0x8BEE, },
	{ .name = "SIOCIWPRIV16", .request = 0x8BEF, },
	{ .name = "SIOCIWLASTPRIV", .request = 0x8BFF, },
};

static const struct ioctl_group socket_grp = {
	.name = "[socket]",
	.fd_test = socket_fd_test,
	.sanitise = pick_random_ioctl,
	.ioctls = socket_ioctls,
	.ioctls_cnt = ARRAY_SIZE(socket_ioctls),
};

REG_IOCTL_GROUP(socket_grp)
